---
title: Method Structure
description: >
  Notes on how to structure methods.
categories: posts
tags: [object-oriented, systematic-design]
---

<details markdown="1" id="table-of-contents">
<summary>
Table of Contents
</summary>

* TOC
{:toc}
</details>

## Intro

Before we talked about how smaller methods lead to cleaner code. In brief, we
should abide by the one-thing principle, where methods handle one level of
abstraction rather than a single operation. Hence, they only have one reason to
change.

Here we elaborate on how a method should be structured in order to handle one
level of abstraction.

## Arguments

Arguments can seem like a convenient way of passing objects around. Nonetheless,
if we don't pay close attention they easily become hard to read an understand.
At that point they become more a liability.

For instance, when a method takes 3 or more arguments we need to remember their
exact order. Passing an options hash doesn't help since we are
still coupling it to external objects. In other words, it depend on too many
things to be able to do its work.

Hence we consider a method better structured if it takes 2 or less arguments.
This only means that you need to create smaller methods that specialize in a
task. If we notice that two or more of those tasks depend on each other, perhaps
they can be extracted into their own method, class or whatever works better.

### Booleans

When we pass a boolean as an argument we are actually writing a method that
does two things. It does one thing for the `true` case, and different one for
the `false` case. Instead, we should write two methods, one for each case.

### Output arguments

If a method returns more than one value at a time your method doesn't have a
single responsibility. So, instead of passing an argument in order to catch the
result of some process within the method simply extract that process into its own
method. There's no need for them in Ruby.

### Nil

A `nil` parameter, just like booleans, shows that our method is in charge of at
least two things. We can either extract one responsibility, go for the NullObject
pattern, or whatever seems more appropriate. Either way, if we are constantly
checking for `nil`s it means our unit tests aren't preventing them from happening.
We should avoid writing defensive code unless we are writing a public API that
could possibly pass invalid data.

## Side effects

We say that a method has side effects when it changes a variable that out lives
the method call. For example, when a method changes the value of an instance
variable.
Side effects are important because they change the behavior of a method or some
other method the next time its called, which is a persistent source of errors.

### Temporal Coupling

Methods with side effects usually come in pairs: set, get, open, close, new, delete,
and so on. This kind of methods have to be called in order (open before close), which
makes them temporarily coupled.

Whenever we have a temporal coupling we can resolve it by passing a block. That
guarantees that everything stays consistent, that methods are always executed in
the right order, and that there are limited side effects.

### Commands and Queries Separation

One way to manage side effects is to create a strong separation between commands
and queries. Methods that return values should not change states; they are queries.
Methods that change state can throw exceptions but they should not return values.

### Tell don't ask

With tell don't ask you aim to reduce the number of queries you do to an object.
An object should deal with its own problems, after all, is the object who knows
it's own state. We don't ever want to ask an object for it's state and then make
decisions on its behalf.
What that means is that public methods should be commands, as oppose to queries.

Chained method calls such as,

```ruby
object.get_x.get_y.get_z.do_something
```

are in clear
violation of tell-don't-ask because we ask many things before we even get to
do something. Instead, aim for code like: `object.do_this` where `object` has
to figure out how to `do_this`. The call to `do_this` will propagate outwards
until it gets to `get_z`.

### Law of Demeter

The Law of Demeter tell us that is a bad idea for single methods to know the
entire navigation structure of a system. The main disadvantage being that it
couples the method to it. Instead, we should strive for methods with very limited
amount of knowledge.

The law of Demeter formalizes "tell don't ask" with the following set of rules:

You may call methods of objects that are:

 - Passed as arguments.
 - Created locally.
 - Instance variables.
 - Globals.

You may not call methods on an object if that object was returned from a previous
method call.

## Internal Organization

In order to show a method's intent we should place all public methods at the top.

On the other hand, private methods should be at the bottom since they hold
implementation details.

We should strive to list all our methods in such a way that no method down below
calls a method that is above. That way, it gets a bit easier to track down a
method's implementation details.

In Ruby, our methods would look like this:

```ruby
class Foo
  # Constants, setters and getters

  # Public methods     -> + Abstract (short names)

  private

  # Private methods    -> + Detailed (long names)
end
```
